package xyz.jcat.seata.example.points.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import xyz.jcat.common.exception.BusinessException;
import xyz.jcat.common.util.JsonUtils;
import xyz.jcat.mybatis.ServiceImpl;
import xyz.jcat.seata.example.api.dto.PointsIncrDto;
import xyz.jcat.seata.example.points.domain.dao.IUserPointsDao;
import xyz.jcat.seata.example.points.domain.po.UserPointsPo;
import xyz.jcat.seata.example.points.service.IUserPointsService;

import java.util.Date;
import java.util.Objects;

@Slf4j
@Service
public class UserPointsService extends ServiceImpl<IUserPointsDao, UserPointsPo> implements IUserPointsService {

    private UserPointsPo getByUserId(Long userId) {
        LambdaQueryWrapper<UserPointsPo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserPointsPo::getUserId, userId);
        return dao.selectOne(queryWrapper);
    }

    @Override
    public void incr(PointsIncrDto pointsIncrDto) {
        //查询用户是否有积分数据
        UserPointsPo userPointsPo = getByUserId(pointsIncrDto.getUserId());
        //没有添加积分记录
        if(Objects.isNull(userPointsPo)) {
            userPointsPo = new UserPointsPo();
            userPointsPo.setUserId(pointsIncrDto.getUserId());
            userPointsPo.setPoints(0L);
            userPointsPo.setFrozenPoints(pointsIncrDto.getPoints());
            userPointsPo.setCreateTime(new Date());
            userPointsPo.setUpdateTime(userPointsPo.getCreateTime());
            dao.insert(userPointsPo);
        }
        //有增加积分
        else {
            int result = dao.incr(userPointsPo.getId(), 0L, pointsIncrDto.getPoints(), new Date());
            if(!SqlHelper.retBool(result)) {
                throw new BusinessException("修改用户积分异常");
            }
        }
    }

    @Override
    public boolean incrUserPointsCommitMethod(BusinessActionContext context) {
        PointsIncrDto pointsIncrDto = getPointsIncrDtoByIncrUserPointsBusinessActionContext(context);
        UserPointsPo userPointsPo = getByUserId(pointsIncrDto.getUserId());
        int result = dao.incr(userPointsPo.getId(), pointsIncrDto.getPoints(), 0 - pointsIncrDto.getPoints(), new Date());
        if(!SqlHelper.retBool(result)) {
            log.error("修改用户积分CommitMethod异常, pointsIncrDto: ()", pointsIncrDto);
            return false;
        }
        return true;
    }

    @Override
    public boolean incrUserPointsRollbackMethod(BusinessActionContext context) {
        PointsIncrDto pointsIncrDto = getPointsIncrDtoByIncrUserPointsBusinessActionContext(context);
        UserPointsPo userPointsPo = getByUserId(pointsIncrDto.getUserId());
        int result = dao.incr(userPointsPo.getId(), 0L, 0 - pointsIncrDto.getPoints(), new Date());
        if(!SqlHelper.retBool(result)) {
            log.error("修改用户积分RollbackMethod异常, pointsIncrDto: ()", pointsIncrDto);
            throw new BusinessException("修改用户积分异常");
        }
        return true;
    }

    private PointsIncrDto getPointsIncrDtoByIncrUserPointsBusinessActionContext(BusinessActionContext context) {
        Object pointsIncrDtoJson = context.getActionContext("pointsIncrDto");
        return JsonUtils.parseObject(pointsIncrDtoJson, PointsIncrDto.class);
    }
}
